package hello

import "fmt"

func PointerTest() {
	fmt.Println("------------ PointerTest() --------------")

	var a int = 4
	var b int32
	var c float32
	var ptr *int
	fmt.Println("ptr 的空值，表示为 : ", ptr)

	if ptr != nil {
		fmt.Println("ptr is not nil")
	} else {
		fmt.Println("ptr is nil")
	}

	/* 运算符实例 */
	fmt.Printf("第 1 行 - a 变量类型为 = %T\n", a)
	fmt.Printf("第 2 行 - b 变量类型为 = %T\n", b)
	fmt.Printf("第 3 行 - c 变量类型为 = %T\n", c)

	/*  & 和 * 运算符实例 */
	ptr = &a /* 'ptr' 包含了 'a' 变量的地址 */
	fmt.Printf("a 的值为 %d\n", a)
	fmt.Printf("a 的地址为 %X\n", &a)
	fmt.Printf("*ptr 为 %d\n", *ptr)
	fmt.Printf("ptr 为HEX： %X\n", ptr)
	fmt.Printf("ptr 为%%p %p\n", ptr)
}

func PointerTest2() {
	fmt.Println("------------ PointerTest2() --------------")

	var a int
	var ptr *int
	var pptr **int

	a = 3000

	/* 指针 ptr 地址 */
	ptr = &a

	/* 指向指针 ptr 地址 */
	pptr = &ptr

	/* 获取 pptr 的值 */
	fmt.Printf("变量 a = %d\n", a)
	fmt.Printf("指针变量 *ptr = %d\n", *ptr)
	fmt.Printf("指向指针的指针变量 **pptr = %d\n", **pptr)

}

func PointerTest3() {
	fmt.Println("------------ PointerTest3() --------------")

	var a int = 5
	var ptr *int = &a     // 把ptr指针 指向ss所在地址
	var pts *int = ptr    // 开辟一个新的指针，指向ptr指针指向的地方
	var pto **int = &ptr  // 二级指针，指向一个地址，这个地址存储的是一级指针的地址
	var pt3 ***int = &pto // 三级指针，指向一个地址，这个地址存储的是二级指针的地址，二级指针同上

	fmt.Println("a的地址:", &a,
		"\n 值", a, "\n\n",

		"ptr指针所在地址:", &ptr,
		"\n ptr指向的地址:", ptr,
		"\n ptr指针指向地址对应的值", *ptr, "\n\n",

		"pts指针所在地址:", &pts,
		"\n pts指向的地址:", pts,
		"\n pts指针指向地址对应的值:", *pts, "\n\n",

		"pto指针所在地址:", &pto,
		"\n pto指向的指针（ptr）的存储地址:", pto,
		"\n pto指向的指针（ptr）所指向的地址: ", *pto,
		"\n pto最终指向的地址对应的值（a）", **pto, "\n\n",

		"pt3指针所在的地址:", &pt3,
		"\n pt3指向的指针（pto）的地址:", pt3, //等于&*pt3,
		"\n pt3指向的指针（pto）所指向的指针的（ptr）地址", *pt3, //等于&**pt3,
		"\n pt3指向的指针（pto）所指向的指针（ptr）所指向的地址（a）:", **pt3, //等于&***pt3,
		"\n pt3最终指向的地址对应的值（a）", ***pt3)

}
